package com.obas.views{
   import com.ease.core.components.DockableToolBar;
   import com.ease.core.components.DockingView;
   import com.ease.core.components.StageWindow;
   import com.ease.core.components.ToolBar;
   import com.ease.core.components.ViewWindow;
   import com.ease.core.events.LayoutChangeEvent;
   import com.ease.core.events.PerspectiveEvent;
   import com.ease.core.events.ToolBarEvent;
   import com.ease.core.events.ViewOperationEvent;
   import com.ease.core.managers.PerspectiveManager;
   import com.ease.core.managers.ViewManager;
   import com.ease.core.model.ViewDefine;
   import com.ease.util.IconUtil;
   import com.ease.util.ReflectionUtil;
   import com.ease.framework.CommandCompletionEvent;
   import com.ease.framework.CommandSet;
   import com.obas.components.AppStageWindow;
   import com.obas.components.AboutDialog;
   import com.obas.constants.AppConstants;
   import com.obas.constants.StringConstants;
   import com.obas.events.LogoutRequestEvent;
   import com.obas.events.RequestStageMenuDataEvent;
   import com.obas.events.RequestUserSessionEvent;
   import com.obas.flex.common.event.SessionTimeoutEvent;
   import com.obas.flex.common.util.ClientErrorUtil;
   import com.obas.menus.PerspectiveBoxMenu;
   import com.obas.model.visualobject.PerspectiveToggleItem;
   import com.obas.plugin.PluginManager;
   import com.obas.utils.ResourceUtil;
   import com.ease.workbench.common.IEntityView;
   import com.ease.model.term.CoolBar;
   import com.ease.model.term.CoolMenu;
   import com.ease.model.term.CoolPerspective;
   import com.ease.model.term.CoolPlugin;
   import com.ease.component.controls.menu.MenuItem;
   import com.ease.component.managers.ConfirmHelper;
   import com.ease.component.managers.ErrorManager;
   import com.ease.component.managers.ProgressManager;
   import com.ease.kernel.Kernel;
   
   import flash.events.Event;
   import flash.events.EventDispatcher;
   import flash.utils.Dictionary;
   
   import mx.collections.ArrayCollection;
   import mx.collections.Sort;
   import mx.collections.SortField;
   import mx.core.FlexGlobals;
   import mx.core.IFlexDisplayObject;
   import mx.core.UIComponent;
   import mx.events.MenuEvent;
   import mx.managers.PopUpManager;

   [Event(name="{com.obas.events.LogoutRequestEvent.REQUEST_ID}",
      type="com.obas.events.LogoutRequestEvent")]
   [Event(name="{com.obas.events.RequestUserSessionEvent.REQUEST_ID}",
      type="com.obas.events.RequestUserSessionEvent")]
   [Event(name="{com.ease.core.events.ViewOperationEvent.REQUEST_ID}",
      type="com.ease.core.events.ViewOperationEvent")]
   [Event(name="{com.ease.core.events.PerspectiveEvent.REQUEST_ID}",
      type="com.ease.core.events.PerspectiveEvent")]
   [Event(name="{com.obas.events.RequestStageMenuDataEvent.REQUEST_ID}",
      type="com.obas.events.RequestStageMenuDataEvent")]
   public class MainWindowMediator extends EventDispatcher {
      private var _perspectiveManager:PerspectiveManager = PerspectiveManager.getInstance();
      private var _viewManager:ViewManager = ViewManager.getInstance();
      private var perspectiveViewCache:Dictionary = new Dictionary();
      private var showViewMenu:MenuItem;
      private var showPerspectiveMenu:MenuItem;
      private var windowMenu:MenuItem;
      private var helpMenu:MenuItem;
      private var aboutSysMenu:MenuItem;

      private var _view:MainWindow;
      [InjectableView]
      public function get view():MainWindow {
         return _view;
      }

      public function set view(value:MainWindow):void {
         _view = value;
         init();
      }

      private function init():void {
         initSystemMenu();
         initSessionInfo();
         initPerspectiveBox();
      }

      private function initSessionInfo():void {
         dispatchEvent(new RequestUserSessionEvent(null));
      }

      [ResponseHandler("{com.obas.events.RequestUserSessionEvent.RETURN_ID}")]
      public function onRequestUserSessionEvent(event:CommandCompletionEvent):void {
         if (event.error) {
            ErrorManager.showErrorMessage(ClientErrorUtil.getErrorString("", "", event.error));
            return;
         }

         FlexGlobals.topLevelApplication.appContextData.currentUserId = event.result.id;
         FlexGlobals.topLevelApplication.appContextData.currentUserName = event.result.name;
         FlexGlobals.topLevelApplication.appContextData.username = event.result.username;
      }

      private function initSystemMenu():void {

         windowMenu = new MenuItem();
         windowMenu.label = "窗口";
         windowMenu.toggled = false;
         windowMenu.children = [];
         showPerspectiveMenu = new MenuItem();
         showPerspectiveMenu.label = "打开透视图";
         showPerspectiveMenu.toggled = false;
         appendPerspectiveMenu(showPerspectiveMenu);
         windowMenu.children.push(showPerspectiveMenu);
         showViewMenu = new MenuItem();
         showViewMenu.label = "显示视图";
         showViewMenu.toggled = false;
         showViewMenu.children = [];
         windowMenu.children.push(showViewMenu);
         var reset:MenuItem = new MenuItem();
         reset.label = "恢复透视图";
         reset.toggled = false;
         reset.clickEventType = AppConstants.RESET_PERSPCTIVE_MENU_EVENT;
         windowMenu.children.push(reset);

         helpMenu = new MenuItem();
         helpMenu.label = "帮助";
         helpMenu.toggled = false;
         helpMenu.children = [];
         aboutSysMenu = new MenuItem();
         aboutSysMenu.label = "关于应用系统";
         aboutSysMenu.clickEventType = AppConstants.ABOUT_SYSTEM_MENU_EVENT;
         helpMenu.children.push(aboutSysMenu);

         _view.sysMenuBar.addEventListener(MenuEvent.ITEM_CLICK,showSysMenuItem);
         _perspectiveManager.addEventListener(LayoutChangeEvent.UPDATE, onLayoutChange);
//         _view.logoutBtn.addEventListener(MouseEvent.CLICK, onLogout);
//         _view.changePwdBtn.addEventListener(MouseEvent.CLICK, onChangePwd);
      }

//      private function onLogout(event:*):void {
//         ProgressManager.showProgress(_view, ProgressManager.LOADING_SPINNER);
//         dispatchEvent(new LogoutRequestEvent());
//      }
//
//      private function onChangePwd(e:*):void {
//         var window:ChangeUserPasswordView = new ChangeUserPasswordView();
//         window.user =  _view.currentUser;
//         _view.callLater(callLaterPopupHandler, [window]);
//      }

      private function callLaterPopupHandler(popupWindow:IFlexDisplayObject):void {
         PopUpManager.addPopUp(popupWindow, _view.root, true);
         PopUpManager.centerPopUp(popupWindow);
      }

      [ResponseHandler("{com.obas.events.LogoutRequestEvent.RETURN_ID}")]
      public function onLoginRequestEvent(event:CommandCompletionEvent):void {
         ProgressManager.hideProgress(_view);
         if (event.error) {
            ConfirmHelper.showErrorDialog("", decodeURI(event.error.message));
            return;
         }

      }

      [EventHandler("{com.obas.flex.common.event.SessionTimeoutEvent.SESSION_TIMEOUT}")]
      public function onServerSideSesstionTimeout(event:SessionTimeoutEvent):void {
      }

      private function appendPerspectiveMenu(menu:MenuItem):void {
         menu.children = [];

         for each (var perspectiveId:String in _perspectiveManager.perspectiveIds) {
            var perspective:CoolPerspective = _perspectiveManager.getPerspective(perspectiveId) as CoolPerspective;
            var menuItem:MenuItem = new MenuItem();
            menuItem.label = perspective.name;
            if (perspective.icon) {
               menuItem.icon = IconUtil.getClass(menuItem, perspective.icon, 16, 16);
            }
            menuItem.clickEventType = AppConstants.SHOW_PERSPCTIVE_MENU_EVENT;
            menuItem.data = perspective;
            menuItem.type = "check";
            menu.children.push(menuItem);
         }
      }

      private function onLayoutChange(event:LayoutChangeEvent):void {
         var menuItems:Array = showViewMenu.children;
         for each (var item:MenuItem in menuItems) {
            var viewDef:ViewDefine = item.data as ViewDefine;
            var view:DockingView = _viewManager.createViewInstance(viewDef.id, _perspectiveManager.activePerspective) as DockingView;
            item.toggled = view && view.parent;
         }
      }

      private function resetMenu(perspective:String):void {
         if (!perspective)
            return;
         showViewMenu.children = [];
         var layoutXml:XML = XML((_perspectiveManager.getPerspective(perspective) as CoolPerspective).layout).layout[0];
         var views:XMLList = layoutXml..View;
         for each (var viewXML:XML in views) {
            var viewDef:ViewDefine = _viewManager.getViewDefine(viewXML.@id);
            var menuItem:MenuItem = new MenuItem();
            menuItem.label = viewDef.label;
            if (viewDef.icon) {
               menuItem.icon = IconUtil.getClass(menuItem, viewDef.icon, 16, 16);
            }
            menuItem.clickEventType = AppConstants.SHOW_VIEW_MENU_EVENT;
            menuItem.data = viewDef;
            menuItem.type = "check";
            menuItem.groupName = perspective;
            var view:DockingView = _viewManager.createViewInstance(viewDef.id, perspective) as DockingView;
            menuItem.toggled = view && view.parent;
            showViewMenu.children.push(menuItem);
         }

         var perspectiveItems:Array = showPerspectiveMenu.children;
         for each (var item:MenuItem in perspectiveItems) {
            var perspectiveView:CoolPerspective = item.data as CoolPerspective;
            item.toggled = perspectiveView.code == perspective;
         }
      }

      private function showSysMenuItem(e:MenuEvent):void {
         var item:MenuItem = e.item as MenuItem;
         if (item.clickEventType == AppConstants.SHOW_VIEW_MENU_EVENT) {
            var viewDef:ViewDefine = item.data as ViewDefine;
            var view:DockingView = _viewManager.createViewInstance(viewDef.id, _perspectiveManager.activePerspective) as DockingView;
            if (view) {
               if (!view.parent) {
                  var stageWindow:StageWindow = _view.stageWindow.selectedChild as StageWindow;
                  stageWindow.openView(view, 0);
               }
            }
            item.toggled = true;
            if (view.parent) {
               (view.parent as ViewWindow).selectedChild = view;
            }
         }
         else if (item.clickEventType == AppConstants.SHOW_PERSPCTIVE_MENU_EVENT) {
            var perspective:CoolPerspective = item.data as CoolPerspective;
            openPerspective(perspective.code);
         }
         else if (item.clickEventType == AppConstants.STAGE_MENU_EVENT) {
            var param:Object = e.item.data as Object;
            param.title = item.label;
            dispatchEvent(new ViewOperationEvent([param.targetView], param));
         }
         else if (item.clickEventType == AppConstants.RESET_PERSPCTIVE_MENU_EVENT) {
            var appStageWindow:AppStageWindow = _view.stageWindow.selectedChild as AppStageWindow;
            appStageWindow.openPerspective(_perspectiveManager.activePerspective);
         }
         else if (item.clickEventType == AppConstants.ABOUT_SYSTEM_MENU_EVENT) {
            var systemInfoDialog:AboutDialog = PopUpManager.createPopUp(_view.root, AboutDialog, true) as AboutDialog;
            PopUpManager.centerPopUp(systemInfoDialog);
         }
      }

      private function initPerspectiveBox():void {
      // view.toolbarToggle.addEventListener(MouseEvent.CLICK, onToggleButtonClick);
         view.addEventListener(PerspectiveBoxMenu.SHOW_TEXT, onShowPerspectiveText);
         _view.perspectiveBox.labelFunction = perspectiveLabelFunction;
         _view.perspectiveBox.iconField = "iconClass";

         var items:ArrayCollection = new ArrayCollection();
         for each (var perspectiveId:String in _perspectiveManager.perspectiveIds) {
            var perspective:CoolPerspective = _perspectiveManager.getPerspective(perspectiveId) as CoolPerspective;
            var item:PerspectiveToggleItem = new PerspectiveToggleItem();
            item.perspectiveId = perspectiveId;
            item.label = perspective.name;
            item.ordinal = perspective.ordinal;
            if (perspective.icon) {
               item.iconClass = IconUtil.getClass(item, perspective.icon, 16, 16);
            }
            items.addItem(item);
         }
         var field:SortField = new SortField();
         field.name = "ordinal";
         field.numeric = true;
         var sort:Sort = new Sort();
         sort.fields = [field];

         items.sort = sort;
         items.refresh();
         _view.perspectiveBox.perspectiveItems = items;
         openPerspective(items.getItemAt(0).perspectiveId);
      }

      private function onToggleButtonClick(event:*):void {
      //TBD 去掉toolbar
      //   view.toolBar.visible = view.toolBar.includeInLayout = ! view.toolBar.visible;
      }

      private function onShowPerspectiveText(event:*):void {
         showPerspectiveLabel = !showPerspectiveLabel;
         var selectedIndex:int = view.perspectiveBox.perspectiveBar.selectedIndex;
         view.perspectiveBox.perspectiveItems.refresh();
         view.perspectiveBox.perspectiveBar.selectedIndex = selectedIndex;
      }

      private var showPerspectiveLabel:Boolean = true;
      private function perspectiveLabelFunction(item:Object):String {
         return showPerspectiveLabel? item.label : null;
      }

      [EventHandler("{com.ease.core.events.ViewOperationEvent.REQUEST_ID}")]
      public function onViewOperation(event:ViewOperationEvent):void {
         if(event.actionType == ViewOperationEvent.TYPE_OPEN_VIEW) {
            for each (var viewId:String in event.viewIds) {
               if (!viewId) {
                  var viewType:String = event.spec.className;
                  var viewDg:UIComponent = ReflectionUtil.newInstance(viewType, null) as UIComponent;
                  IEntityView(viewDg).appendParameter(event.spec);
                  PopUpManager.addPopUp(viewDg, _view.root, true);
                  PopUpManager.centerPopUp(viewDg);
                  return;
               }
               var createNew:Boolean = event.spec.hasOwnProperty("createNew")? event.spec.createNew == "true" : false;
               var autoOpen:Boolean = event.spec.hasOwnProperty("autoOpen")? event.spec.autoOpen == "true" : true;
               var view:DockingView = null;
               var views:Array = _viewManager.getViewInstance(viewId, _perspectiveManager.activePerspective);
               if (!views || views.length == 0) {
                  view =  _viewManager.createViewInstance(viewId, _perspectiveManager.activePerspective);
                  openViewAndAppendParam(view, event.spec, autoOpen);
               }
               else {
                  if (createNew) {
                     for each (view in views) {
                        if (view.checkParam(event.spec)) {
                           openViewAndAppendParam(view, event.spec, autoOpen);
                           return;
                        }
                     }
                     view =  _viewManager.createViewInstance(viewId, _perspectiveManager.activePerspective, true);
                     openViewAndAppendParam(view, event.spec, autoOpen);
                     (view.parent as ViewWindow).selectedChild = view;
                  }
                  else {
                     for each (view in views) {
                        openViewAndAppendParam(view, event.spec, autoOpen);
                     }
                  }
               }
            }
         }
         else if(event.actionType == ViewOperationEvent.TYPE_CLOSE_VIEW) {
            for each (var closeViewId:String in event.viewIds) {
               var closeViews:Array = _viewManager.getViewInstance(closeViewId, _perspectiveManager.activePerspective);
               if (event.spec) {
                  for each (var closeView:DockingView in closeViews) {
                     if (closeView == event.spec) {
                        if (closeView.parent) {
                           closeView.parent.removeChild(closeView);
                        }
                        closeView.dispose();
                     }
                  }
               }
               else {
                  for each (closeView in closeViews) {
                     if (closeView && closeView.parent) {
                        closeView.parent.removeChild(closeView);
                     }
                     closeView.dispose();
                  }
               }
            }
         }
      }

      private function openViewAndAppendParam(view:DockingView, param:Object, autoOpen:Boolean):void {
         var opened:Boolean = false;
         if (view) {
            if (!view.parent && autoOpen) {
               var stageWindow:StageWindow = _view.stageWindow.selectedChild as StageWindow;
               stageWindow.openView(view);
               opened = true;
            }
            if (view.parent) {
               if ((ViewWindow(view.parent).selectedChild as DockingView).viewId != view.viewId) {
                  (view.parent as ViewWindow).selectedChild = view;
               }
               opened = true;
            }
         }
         if (opened) {
            view.appendParam(param);
         }
      }

      [EventHandler("{com.ease.core.events.PerspectiveEvent.REQUEST_ID}")]
      public function onPerspectiveOperation(event:PerspectiveEvent):void {
         if(event.actionType == PerspectiveEvent.TYPE_OPEN) {
            openPerspective(event.perspectiveId);
         }
      }

      private function openPerspective(perspectiveId:String):void {
         loadToolbarAndMenu(perspectiveId);
         loadPlugin(perspectiveId);
      }

      private function loadToolbarAndMenu(perspectiveId:String):void {
         dispatchEvent(new RequestStageMenuDataEvent([perspectiveId]));
      }

      [ResponseHandler("{com.obas.events.RequestStageMenuDataEvent.RETURN_ID}")]
      public function onRequestStageMenuDataEvent(event:CommandCompletionEvent):void {
         var request:RequestStageMenuDataEvent = event.request as RequestStageMenuDataEvent;
         if (event.error) {
            ErrorManager.showErrorMessage(
               ResourceUtil.getString(StringConstants.MAIN_MENU_ERROR, [event.error.message]));
            return;
         }
         if (request.actionType == RequestStageMenuDataEvent.TYPE_GET_MENU) {
            var menuDatas:ArrayCollection = event.result as ArrayCollection;
            if (menuDatas && menuDatas.length > 0) {
               view.sysMenuData = getMenuItemsFromData(menuDatas.source);
            }
            else {
               view.sysMenuData = [];
            }

            view.sysMenuData.push(windowMenu, helpMenu);
         }
         else {
            var bars:ArrayCollection = event.result as ArrayCollection;
//            _view.toolBox.removeAllChildren();
            for each (var bar:CoolBar in bars) {
               var dockBar:DockableToolBar = new DockableToolBar();
               dockBar.id = bar.id + "";
               dockBar.label = bar.name;
               dockBar.draggable = true;
               var toolBar:ToolBar = new ToolBar();
               toolBar.labelField = "name";
//               toolBar.dataProvider = bar.buttons;
               toolBar.addEventListener(ToolBarEvent.CLICK, onToolBarClick);
               dockBar.addChild(toolBar);
//               _view.toolBox.addChild(dockBar);
            }
         }
      }

      private function onToolBarClick(event:ToolBarEvent):void {
         var param:Object = event.item.parameterMap as Object;
         var targetView:String = param.targetView;
         dispatchEvent(new ViewOperationEvent(targetView.split(","), param));
      }

      private function loadPlugin(perspectiveId:String):void {
         ProgressManager.showProgress(_view.mainView, ProgressManager.LOADING_SPINNER);
         var perspective:CoolPerspective = _perspectiveManager.getPerspective(perspectiveId) as CoolPerspective;
         if (perspective.coolPlugin) {
            var plugin:CoolPlugin = perspective.coolPlugin;
            var urls:Array = [];
//            if (plugin.referencePlugins && plugin.referencePlugins.length > 0) {
//               for each (var refPlugin:CoolPlugin in plugin.referencePlugins) {
//                  if (refPlugin.url) {
//                  if (refPlugin.url && plugin.name != "topo_plugin.swf" && plugin.name != "osp_plugin.swf" && plugin.name != "process_plugin.swf" ) {
//                     urls.push(refPlugin.url);
//                  }
//               }
//            }
            if (plugin.url && urls.indexOf(plugin.url) == -1) {
               urls.push(plugin.url);
            }
            var loader:PluginManager = new PluginManager();
            loader.addEventListener(Event.COMPLETE, onLoadComplete);
            loader.loadPlugin(urls);

            function onLoadComplete(e:*):void {
               var commands:ArrayCollection = Kernel.getInstance(CommandSet).
                  getServices(AppConstants.EXTENSION_COMMAND_SET) as ArrayCollection;
               for each (var commandSet:CommandSet in commands) {
                  FlexGlobals.topLevelApplication.appCommands.registry.addCommandSet(commandSet);
               }
               commands.removeAll();
               if (perspectiveViewCache[perspectiveId]) {
                  _view.stageWindow.selectedChild = perspectiveViewCache[perspectiveId];
                  _perspectiveManager.activePerspective = perspectiveId;
                  dispatchEvent(new PerspectiveEvent(perspectiveId, null, PerspectiveEvent.TYPE_OPENED));
               }
               else {
                  var stage:AppStageWindow = new AppStageWindow();
                  stage.perspective = perspectiveId;
                  stage.stageWindowBar = _view.stageWindowBar;
                  _view.stageWindowBar.stageWindow = stage;
                  perspectiveViewCache[perspectiveId] = stage;
                  _view.stageWindow.addChild(stage);
                  _view.stageWindow.selectedChild = stage;
               }
               resetMenu(perspectiveId);
               ProgressManager.hideProgress(_view.mainView);
            }
         }
      }

      public static function getMenuItemsFromData(menuDatas:Array):Array {
         if (!menuDatas || menuDatas.length == 0)
            return null;
         var result:Array = new Array();
         for each (var data:CoolMenu in menuDatas) {
            if (!data.visible) {
               continue;
            }
            var item:MenuItem = new MenuItem();
            item.data = data.parameterMap;
            item.label = data.name;
            if (data.icon) {
               item.icon = IconUtil.getClass(item, data.icon, 16, 16);
            }
            item.visible = data.visible;
            item.enabled = data.enable;
            if (data.childrenCoolMenus && data.childrenCoolMenus.length > 0) {
               item.children = getMenuItemsFromData(data.childrenCoolMenus.source);
            }
            item.clickEventType = AppConstants.STAGE_MENU_EVENT;
            result.push(item);
         }
         return result;
      }
   }
}